package parser;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import parser.exceptions.InvalidTemplateException;

import leerxml.TemplateStructure;

import net.htmlparser.jericho.Attribute;
import net.htmlparser.jericho.Attributes;
import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.HTMLElementName;
import net.htmlparser.jericho.Source;
import net.htmlparser.jericho.StartTag;
import net.htmlparser.jericho.TextExtractor;

public class Sad {
	
	private static final String EQUAL = "=";
	private static final String SLASH = "/";
	private static final String ROOT = "root";
	private String title;
	private boolean tittleSet= false;
	private List<TemplateStructure> templateStructure;
	private Source wikiSource;
	
	public Sad(String urlBase, List<TemplateStructure> templateFormat, Source source) {
		this.urlBase= urlBase;
		this.documentContent = new ElementoCompuesto(this);
		this.templateStructure=templateFormat;
		this.wikiSource = source;
		
	}

	/**
	 * @return the urlBase
	 */
	public String getUrlBase() {
		return urlBase;
	}

	/**
	 * @param urlBase the urlBase to set
	 */
	public void setUrlBase(String urlBase) {
		this.urlBase = urlBase;
	}

	private String urlBase;
	
	private ElementoCompuesto documentContent;
	
	private DocumentRoadMap documentRoadMap;
	private ArchitectureBackground architectureBackground;
	private boolean documentRoadMapGenerated=false;
	private boolean architectureBackgroundGenerated=false;

	/**
	 * @return the documentRoadMap
	 */
	public DocumentRoadMap getDocumentRoadMap() {
		return documentRoadMap;
	}

	/**
	 * @param documentRoadMap the documentRoadMap to set
	 */
	public void setDocumentRoadMap(DocumentRoadMap documentRoadMap) {
		this.documentRoadMap = documentRoadMap;
		this.documentRoadMapGenerated=true;
	}

	/**
	 * @return the title
	 */
	public String getTitle() {
		return title;
	}

	/**
	 * @param title the title to set
	 */
	public void setTitle(String title) {
		this.title = title;
		this.tittleSet= true;
	}

	/**
	 * @return the tittleSet
	 */
	public boolean isTittleSet() {
		return tittleSet;
	}

	/**
	 * @return the contenido
	 */
	public ElementoCompuesto getContenido() {
		return documentContent;
	}

	/**
	 * @param contenido the contenido to set
	 */
	public void setContenido(ElementoCompuesto contenido) {
		this.documentContent = contenido;
	}

	public boolean isDocumentoRoadMapGenerated() {
		
		return this.documentRoadMapGenerated;
	}

	public boolean isArchitectureBackgroundGenerated() {
		
		return this.architectureBackgroundGenerated;
	}

	public void generate() throws Exception {
		
		
//		Iterator<Element> elementos = processTitle();
		
		List<Element> lista=this.wikiSource.getChildElements();
		//[0]--> Doctype
		//[1]--> Html
		Element tagHtml= lista.get(1);
		List<Element> htmlChilds= tagHtml.getChildElements();
		//[0]--> Head
		//[1]--> Body
		Element tagBody = htmlChilds.get(1);
		List<Element> bodyChilds= tagBody.getChildElements();
		Iterator<Element> elementos = bodyChilds.iterator();
		
		Iterator<Element> subElement = elementos.next().getChildElements().iterator();
		 subElement = subElement.next().getChildElements().iterator();
		 subElement = subElement.next().getChildElements().iterator();
		subElement.next();
		subElement.next();
		Iterator<TemplateStructure> templateIter =this.templateStructure.iterator();
		UrlWrapper urlsWrapper = new UrlWrapper();
		urlsWrapper.setText(ROOT);
		int cantSectionInTemplate=  getCantSection();
		int cantItemTemplate= getCantItem();
		
		if(subElement.hasNext())
			parse(urlsWrapper,subElement, subElement.next(),templateIter,templateIter.next(),false);
		
		
		
		
		int cantSectonInWrapper= urlsWrapper.getCantSections() -1;//menos uno porq el root no se cuenta
		int cantItemInWrapper= urlsWrapper.getCantItems();		
				
		if(estructuraValida(this.templateStructure.iterator(),urlsWrapper.getChildUrls().iterator())){
			System.out.println("La estructura es valida! Coincide con el Template!");
		}else
		{
			System.out.println("La estructura NO es valida!");
	
			urlsWrapper.setValid(false);
		}
		urlsWrapper.toString();
//		generateModel(elementos,urlsWrapper);
		
		
	}

	private boolean estructuraValida(Iterator<TemplateStructure> templateIter,
			Iterator<UrlWrapper> urlsWrapperList) {
		boolean rta= false;
		if(templateIter.hasNext() && urlsWrapperList.hasNext() ){
			TemplateStructure templateNode= templateIter.next();
			UrlWrapper urlWrapp= urlsWrapperList.next();
			if((templateNode.isItem() && urlWrapp.getChildUrls().size()==0) || (!templateNode.isItem() && templateNode.getStrcture().size()==0)){				
				rta= true && estructuraValida(templateIter, urlsWrapperList);
				}else{
					rta= estructuraValida(templateNode.getStrcture().iterator(), urlWrapp.getChildUrls().iterator()) &&  estructuraValida(templateIter, urlsWrapperList);
				}
			}else{
				if(!templateIter.hasNext() && !urlsWrapperList.hasNext()){
					rta=true;
				}
				else{
					rta=false;
				}
			}		
		
		
		return rta;
	}

	private int getCantItem() {
    
		int cant=0;
		
		for (int i = 0; i < templateStructure.size(); i++) {
			TemplateStructure structure= templateStructure.get(i);
			cant+= structure.getCantItems();	
		}
		
		return cant;
	}

	private boolean estructuraValida(int cantSectionInTemplate,
			int cantSectonInWrapper, int cantItemTemplate, int cantItemInWrapper) {
		
		return cantSectionInTemplate <= cantSectonInWrapper && cantItemTemplate <= cantItemInWrapper ;
	}

	private int getCantSection() {
		int cant=0;
		
		for (int i = 0; i < templateStructure.size(); i++) {
			TemplateStructure structure= templateStructure.get(i);
			cant+= structure.getCantSections();
			
		}
		
		
		
		return cant;
	}

	private void generateModel(Iterator<Element> elementos, UrlWrapper urlsWrapper) throws InvalidTemplateException {
		
		
//		List<Attribute> urls=  this.wikiSource.getURIAttributes();
		UrlWrapper links= getSectionUrls(urlsWrapper);
		if(links!=null){
			
			documentContent= generateContent(links,templateStructure.iterator().next());
			
		}else{
			
			throw new InvalidTemplateException();
		}
		
	}

	private ElementoCompuesto generateContent(UrlWrapper urls, TemplateStructure templateStructure) {
		// TODO Auto-generated method stub
		return null;
	}

	private UrlWrapper getSectionUrls(UrlWrapper urlsWrapper) throws InvalidTemplateException {
		
		UrlWrapper links = null;
//		String urlToMatch = "";
//		boolean matching= false;
		String[] url= null;
		int urlsIndex=0;
		int templateIndex=0;
		UrlWrapper urlW = null;
		TemplateStructure templateElement = this.templateStructure.get(templateIndex);
		boolean firstFoundUrl= false;
		List<UrlWrapper> urlList= urlsWrapper.getChildUrls();
		boolean valid= false;
		while(urlsIndex < urlList.size() && !valid){
				
				urlW = urlList.get(urlsIndex);
				url= urlW.getLinkRaw().split(SLASH);
				//Encontre primer matching recorro estructuras recursivamente
				if(match(url[url.length-1],templateElement)){
					cleanUrlWrapper(urlList,urlsIndex);
//					List<UrlWrapper> urlList = wrap(urls);
					Iterator<UrlWrapper> urlsIter= urlList.iterator();
			 	    Iterator<TemplateStructure> templateIter = this.templateStructure.iterator();
					valid= validate(urlsIter,urlsIter.next(),templateIter,templateIter.next(),false);
//					cleanUrlWrapper(urlsWrapper.getChildUrls());
//					//ver cuando valida como liampiar las sobrar.. y probar porque fallo en un caso
////					firstFoundUrl= true;
////					templateIndex++;
////					templateElement = this.templateStructure.get(templateIndex);
////					links.add(urlW);
				}//else{
//					if(firstFoundUrl){
//						if(templateElement.isItem()){
//							throw new InvalidTemplateException();
//						}cleanU
//						else{
//							templateIndex++;
//							templateElement = this.templateStructure.get(templateIndex);
//							urlsIndex--;
//							
//						}
//							
//					}
//				}
//				
				urlsIndex++;
				
			}
		
//		if(templateIndex < this.templateStructure.size()){
//				//No recorri todo el template y ya recorri todas las url. Formato invalido
//				links.clear();
//			}
				
		
		
		
		return links;
	}

	private List<UrlWrapper> wrap(List<Attribute> urls) {
		List<UrlWrapper> returnList= new ArrayList<UrlWrapper>();
		for (int i = 0; i < urls.size(); i++) {
			returnList.add(new UrlWrapper(urls.get(i)));
		}
		return returnList;
	}

	private void cleanUrlWrapper(List<UrlWrapper> childUrls) {
		for (int i = 0; i <childUrls.size(); i++) {
			UrlWrapper urlItem = childUrls.get(i);
			if(!urlItem.isVAlid()){
				childUrls.remove(i);
				i--;
			}
		}
		
	}

	private void cleanUrlWrapper(List<UrlWrapper> urls, int urlsIndex) {
		
		
		for (int i = 0; i < urlsIndex; i++) {
			urls.remove(0);
			
		}
		
	}

//	private boolean validate(Iterator<UrlWrapper> urlsIter,
//			UrlWrapper urlW, Iterator<TemplateStructure> templateIter, TemplateStructure templateElement, boolean descartarHijos) {
//		
//		
//		
//		String[] url = urlW.getAtt().getValue().split(SLASH);
//		String link= url[url.length-1];
//		
//		
//		if(match(link, templateElement)){
//			/**
//			 * si tiene hijos el template
//			 */
//			if(!templateElement.isItem()){
//				
//				
//				Iterator<TemplateStructure> subItemTemplateIter= templateElement.getStrcture().iterator();
//				
//				if(urlsIter.hasNext() && subItemTemplateIter.hasNext()){
//					UrlWrapper nextUrl= urlsIter.next();
//					TemplateStructure nextTemplateItem= subItemTemplateIter.next();
//					urlW.setValid();
//				     //       hijos                                                                 hermanos
// 					return validate(urlsIter,urlsIter.next(),subItemTemplateIter,nextTemplateItem,descartarHijos) && validate(urlsIter,urlsIter.next(),templateIter,templateIter.next(),descartarHijos);
//					
//				}else{
//					if(childIter.hasNext()){
//						//esa rama esta validada hay que seguir por la siguiente y desartar esos hijos
//						 urlW.setValid();
//						return true && validate(urlsIter,urlsIter.next(),templateIter,templateIter.next(),descartarHijos) ;
//					}else
//						//ver
//						return validate(childIter,urlW,subItemTemplateIter,subItemTemplateIter.next(),descartarHijos);
//				}
//				
//				
//			}else{
//				/**
//				 * Es un item entonces adelanto sigo validando el item siguiente de ambas estructuras
//				 */
//				if(urlsIter.hasNext() && templateIter.hasNext()){
//					urlW.setValid();
//					return validate(urlsIter,urlsIter.next(),templateIter,templateIter.next(),descartarHijos );
//			   }else{
//				   //Ver
//				   urlW.setValid();
//				   return true;
//			   }
//			}
//			
//			
//		}else{
//			
//			/**
//			 * Si no hay maching puede ser por:
//			 * formato invalido--> devolver false y listo
//			 * entrada en el indice sin link, hay que adelantar en el template
//			 * 
//			 * 
//			 */
//			if(templateElement.isItem()){
//				
//				return false;
//			}else{
//				if(descartarHijos){
//					urlW.setValid();
//					if(!match(link, templateElement)){
//						if(urlsIter.hasNext()){
//							return validate(urlsIter,urlsIter.next(),templateIter,templateElement,true);
//						}else{
//						
//						Iterator<TemplateStructure> subItemIter= templateElement.getStrcture().iterator();
//						if(subItemIter.hasNext()){
//							return validate(urlsIter,urlsIter.next(),subItemIter,subItemIter.next(),true);
//						}
//					}
//					}
//					else{
//						
//						return validate(urlsIter,urlW,templateIter,templateElement,false);
//					}
//						
//				}
//				
//				Iterator<TemplateStructure> subItemIter= templateElement.getStrcture().iterator();
//				if(subItemIter.hasNext()){
//					if(templateIter.hasNext()){
//						return validate(urlsIter,urlW,subItemIter,subItemIter.next(),descartarHijos) && validate(urlsIter,urlsIter.next(),templateIter,templateIter.next(),descartarHijos);
//					}else{
//						return validate(urlsIter,urlW,subItemIter,subItemIter.next(),descartarHijos);
//					}
//				}else{
//					
//					
//					
//					return true && validate(urlsIter,urlW,templateIter,templateIter.next(),true) ;
//				}
//			}			
//			
//			
//		}
//		
//		
//		
//		
//	}
	
	private boolean validate(Iterator<UrlWrapper> urlsIter,
			UrlWrapper urlW, Iterator<TemplateStructure> templateIter, TemplateStructure templateElement, boolean descartarHijos) {
		
		
		
		String[] url = urlW.getLinkRaw().split(SLASH);
		String link= url[url.length-1];
		
		
		if(match(link, templateElement)){
			/**
			 * si tiene hijos el template
			 */
			if(!templateElement.isItem()){
				
				Iterator<UrlWrapper> childIter= urlW.getChildUrls().iterator();
				Iterator<TemplateStructure> subItemTemplateIter= templateElement.getStrcture().iterator();
				
				if(childIter.hasNext() && subItemTemplateIter.hasNext()){
					UrlWrapper nextChild= childIter.next();
					TemplateStructure nextTemplateItem= subItemTemplateIter.next();
					urlW.setValid();
				     //       hijos                                                                                       hermanos
 					return validate(childIter,nextChild,subItemTemplateIter,nextTemplateItem,descartarHijos) && validate(urlsIter,urlsIter.next(),templateIter,templateIter.next(),descartarHijos);
					
				}else{
					if(childIter.hasNext()){
						//esa rama esta validada hay que seguir por la siguiente y desartar esos hijos
						 urlW.setValid();
						 urlW.setValidAllChild();
						return validate(urlsIter,urlsIter.next(),templateIter,templateIter.next(),descartarHijos) ;
					}else
						//ver
						return validate(childIter,urlW,subItemTemplateIter,subItemTemplateIter.next(),descartarHijos);
				}
				
				
			}else{
				/**
				 * Es un item entonces adelanto sigo validando el item siguiente de ambas estructuras
				 */
				if(urlsIter.hasNext() && templateIter.hasNext()){
					urlW.setValid();
					return validate(urlsIter,urlsIter.next(),templateIter,templateIter.next(),descartarHijos );
			   }else{
				   //Ver
				   urlW.setValid();
				   return true;
			   }
			}
			
			
		}else{
			
			/**
			 * Si no hay maching puede ser por:
			 * formato invalido--> devolver false y listo
			 * entrada en el indice sin link, hay que adelantar en el template
			 * 
			 * 
			 */
			if(templateElement.isItem()){
				
				return false;
			}else{
				if(descartarHijos){
					urlW.setValid();
					if(!match(link, templateElement)){
						if(urlsIter.hasNext()){
							return validate(urlsIter,urlsIter.next(),templateIter,templateElement,true);
						}else{
						
						Iterator<TemplateStructure> subItemIter= templateElement.getStrcture().iterator();
						if(subItemIter.hasNext()){
							return validate(urlsIter,urlsIter.next(),subItemIter,subItemIter.next(),true);
						}
					}
					}
					else{
						
						return validate(urlsIter,urlW,templateIter,templateElement,false);
					}
						
				}
				
				Iterator<TemplateStructure> subItemIter= templateElement.getStrcture().iterator();
				if(subItemIter.hasNext()){
					if(templateIter.hasNext()){
						return validate(urlsIter,urlW,subItemIter,subItemIter.next(),descartarHijos) && validate(urlsIter,urlsIter.next(),templateIter,templateIter.next(),descartarHijos);
					}else{
						return validate(urlsIter,urlW,subItemIter,subItemIter.next(),descartarHijos);
					}
				}else{
					
					
					
					return true && validate(urlsIter,urlW,templateIter,templateIter.next(),true) ;
				}
			}			
			
			
		}
		
		
		
		
	}
	
	/**
	 * 
	 * seudo marcos
	 * 
	 * / Pa piky
	
	if(template != null && url != null){
		Boolean validate = true;
		if(template.IsSecction()){
			if(template.tieneHijos){
				validate = meMuevo(template.hijos, url);
			}else{
				for(que me avance hasta el siguiente matching);
			}
		}else{
			if(template == url){
				visitas url;
				validate = meMuevo(template.next, url.next);
			}else{
				return false;
			}
		}
	}else{
		return false;
	}
	return validate;
	 */

	private boolean match(String link, TemplateStructure templateElement) {
		
		String title = templateElement.getTitle().replaceAll(" ", "_");
//		String[] titlesPotentials= templateElement.getTitle().split(" ");
//		String titlePotential="";
//		
//		for (int i = 0; i < titlesPotentials.length; i++) {
//			titlePotential= titlesPotentials[i];
//			if(link.contains(titlePotential)){
//				return true;
//			}
//				
//			
//		}		
		//ver esta FIUNCION
		return title.equals(link);
	}

	private Iterator<Element> processTitle() {
		List<Element> lista=this.wikiSource.getChildElements();
		//[0]--> Doctype
		//[1]--> Html
		Element tagHtml= lista.get(1);
		List<Element> htmlChilds= tagHtml.getChildElements();
		//[0]--> Head
		//[1]--> Body
		Element tagBody = htmlChilds.get(1);
		List<Element> bodyChilds= tagBody.getChildElements();
		Iterator<Element> elementos = bodyChilds.iterator();
		
//		parse(elementos,elementos.next());
		Element elemento= elementos.next();	
			
		List<Element> elementosDentroDiv= elemento.getChildElements();
		
		Iterator<Element> elementosDiv =elementosDentroDiv.iterator();
		elemento= elementosDiv.next();
		
		elementosDentroDiv= elemento.getChildElements();
		elementosDiv =elementosDentroDiv.iterator();
		elemento= elementosDiv.next();
		elementosDentroDiv= elemento.getChildElements();
		elementosDiv =elementosDentroDiv.iterator();
		elemento= elementosDiv.next();		
		elemento= elementosDiv.next();		
		 
		if(elemento.getChildElements().size()==0){
			
			//El primer h1 es el titulo
			if(!isTittleSet()){
				if(esTitulo(elemento)){
					setTitle(elemento.getContent().toString());
					System.out.println("Titulo: "+elemento.getContent());
					System.out.println(elemento.getRenderer().toString());
				}
			}
		
		}
		return elementos;
	}

	private void parse(Iterator<Element> elementos, Element elemento) {
		
//		if(this.templateStructure.hasNext()){
			
		
		
		if(elemento !=null ){
			UrlWrapper urlElement = null;
	
			//Elemento simple
			if(elemento.isEmpty()){				
				
				parse(elementos, elementos.next());
			}else{
				
				if(elemento.getChildElements().size()==0){
					
									
//					CCREAR ELEMENTO CON URL if (<a href>) urlElement = new UrlWrapper()
					
//					Lparse(elementos, elemento);
//					
				}else{
				
				//Elemento compuesto
					StartTag tag = elemento.getStartTag();
					
					Iterator<Element> subElement = elemento.getChildElements().iterator();
//					elementSad = new ElementoCompuesto(parentSad);
					parse(subElement,subElement.next());
				
			 }
			}
			if(elementos.hasNext())
				parse(elementos, elementos.next());
		}
		
//	  }
	}

	private void processDocumentRoadMap(Element elemento) {
		
		if(!isDocumentoRoadMapGenerated()){
			
			if(typeA(elemento)){
				
				
				if(getAttValue(elemento,"title").contains("DocumentRoadmap")){
					
					DocumentRoadMap roadMapSection = new DocumentRoadMap(this);
					setDocumentRoadMap(roadMapSection);
					roadMapSection.generate(getUrlBase()+getAttValue(elemento, "href"));
				}
				
			}
			
		}
		
		
	}
	
		
	
	
private boolean esTitulo(Element elemento) {
	
	
	return(elemento.getName().equals(HTMLElementName.H1));
}

private String getAttValue(Element elemento,
		String key) {
	
	String rta="";
	Attributes att= elemento.getAttributes();
	boolean exist=false;
	 if(att!=null){
		 
	 Iterator<Attribute> atributos = att.iterator();
	 while (atributos.hasNext() && !exist) {
	 Attribute atributo = (Attribute) atributos.next();
	   if(atributo.getKey().equals(key))
		  exist= true;
	      rta= atributo.getValue();
	   }
	 }	
	return rta;
}

private boolean typeA(Element elemento) {
	
	return elemento.getName().equals(HTMLElementName.A);
}

private boolean isLink(Element elemento) {
	
	boolean typeA= typeA(elemento);
		
	boolean hrefExist= !"".equals(getAttValue(elemento, "href"));
	return(typeA && hrefExist);
}

public void parse(UrlWrapper urlElement,Iterator<Element> elementos, Element elemento, Iterator<TemplateStructure> templateIter, TemplateStructure templateNode, boolean validarHijos) throws Exception {
	
	
	    UrlWrapper newElement = null;	
	    boolean nextMatch=false;
	    if(urlElement!=null){
		//VEr funcion de matching
				if(matching(elemento, templateNode,validarHijos)){
					 
					if(validarHijos){
						nextMatch= matchingElSiguiente(templateNode,elemento);
						//cambiar las llamadas
					}
					
					newElement = new UrlWrapper();
					
					newElement.setParentUrl(urlElement);
						if(isLink(elemento)){					
							newElement.setLink(getAttValue(elemento, "href"));							
							
						}else{
							
							newElement.setText(templateNode.getTitle());
						}
						//Es item
						if(elemento.getChildElements().size()==0 && templateNode.isItem()){						
								
							if(elementos.hasNext()){
		//						urlElement.addChild(newElement);
		//						newElement.getParentUrl().setValid();
								parse(newElement,elementos, elementos.next(),templateIter,templateIter.next(),nextMatch);					
								}
							else{
		//						newElement.getParentUrl().setValid();
								urlElement.addChild(newElement);					
								
						    }			
							newElement.setValid();
						}else{
							
							//Es seccion 	
							if(!templateNode.isItem()){
								//PAgina con hijos
								if(elemento.getChildElements().size()>0){
								
									Iterator<TemplateStructure> templateChild=  templateNode.getStrcture().iterator();
									Iterator<Element> subElement = elemento.getChildElements().iterator();
									//Agrego a estructura y y llamo con ambos hijos
									
									urlElement.addChild(newElement);
									if(!templateChild.hasNext()){
										//Es una seccion en template pero sin hijos definidos. tengo que generar la estructura pero 
										System.out.println("SeccionVAcia");
										parse(newElement,elementos, elementos.next(),templateIter,templateIter.next(),true);
									}else{
										parse(newElement,subElement, subElement.next(),templateChild,templateChild.next(),nextMatch);
										if(newElement.isVAlid()){
											newElement.setValid();
										}
									}
		//							luego llamo con siguientes tambien
									if(elementos.hasNext()){
										if(newElement.isVAlid()){
											newElement.setValid();
											if(templateIter.hasNext())
												parse(urlElement,elementos,elementos.next(),templateIter, templateIter.next(),nextMatch);
										}else{
											
											parse(urlElement,elementos,elementos.next(),templateChild, templateNode,nextMatch);
										}
										if(urlElement.isVAlid()){
											urlElement.setValid();
										}		
									}
									
										
								}else{// tag sin hijos
									
									Iterator<TemplateStructure> templateChild=  templateNode.getStrcture().iterator();
									
									urlElement.addChild(newElement);
									if(templateChild.hasNext()){
										parse(newElement,elementos, elementos.next(),templateChild,templateChild.next(),nextMatch);
									}else{
										//Section vacia en el template. Tengo que validar todo lo que haya dentro hasta 
										//que haga maching con el siguientenodo del template
										
										parse(newElement,elementos, elementos.next(),templateIter,templateIter.next(),true);
									}
									if(newElement.isVAlid()){
										newElement.setValid();
									}
									if(elementos.hasNext()){
										if(newElement.isVAlid()){
											if(templateChild.hasNext()){
												parse(newElement,elementos,elementos.next(),templateChild, templateChild.next(),nextMatch);
												if(newElement.isVAlid()){
													newElement.setValid();
												}else{
													newElement.setValid(false);
												}
												
											}else{
												if(templateIter.hasNext()){
													parse(urlElement,elementos,elementos.next(),templateIter, templateIter.next(),nextMatch);
													if(urlElement.isVAlid()){
														urlElement.setValid();
													}else{
														newElement.setValid(false);
													}
												}
												
											}
											
										}else{
											parse(newElement,elementos,elementos.next(),templateChild, templateNode,nextMatch);
										
											if(newElement.isVAlid()){
												newElement.setValid();
											}
										}
											
									}
									
								
								}
							
								
							}							
							else
							{//Es un item 
								if(elementos.hasNext()){
									//Iterator<TemplateStructure> templateChild=  templateNode.getStrcture().iterator();
									Iterator<Element> subElement = elemento.getChildElements().iterator();
									//Agrego a estructura y y llamo con hijo de la pagina
									 
		//							 urlElement.addChild(newElement);
									 parse(newElement,subElement, subElement.next(),templateIter,templateNode,nextMatch);
									 // avanzo en ambas estructuras
									
									 if(newElement.isVAlid()){
										 newElement.setValid();
										}
									
									}
								else{
									newElement.setValid();
									urlElement.addChild(newElement);		
									
							    }
							
							}
									
						}			
						
				}else{// No hay matching
					
					 //tiene hijos el tag
					 if(elemento.getChildElements().size()>0){
							
						 Iterator<Element> subElement = elemento.getChildElements().iterator();
						 parse(urlElement,subElement, subElement.next(),templateIter,templateNode,false);
						 if(elementos.hasNext()){
								if(urlElement !=null && urlElement.isVAlid()){
									if(templateIter.hasNext())
									parse(urlElement,elementos,elementos.next(),templateIter, templateIter.next(),nextMatch);
								}else{
									parse(urlElement,elementos,elementos.next(),templateIter, templateNode,nextMatch);
								}
									
							}
						 
						 
						 
					 }else{
						 if(elementos.hasNext()){
		//						
							 parse(urlElement,elementos, elementos.next(),templateIter,templateNode,nextMatch);
						 }
					 }
					 
					 if(urlElement.isVAlid()){
							urlElement.setValid();
					 }else{
						 if( urlElement.getParentUrl()!=null){
						  urlElement.getParentUrl().setValid(false);
						  
						 }else{
							 urlElement.setValid(false);
							
						 }
					 }
				}
		
	    }
	
		 		
}

private boolean matchingElSiguiente(TemplateStructure templateNode,
		Element elemento) {
	boolean rta=false;
	if(isLink(elemento)){
		
		rta=  elemento.getRenderer().toString().equals(templateNode.getTitle());
	}else{
		
		if(elemento.getChildElements().isEmpty()){
			rta=  elemento.getRenderer().toString().equals(templateNode.getTitle());
		}else
		{
			String todo = elemento.getTextExtractor().toString();
			String resto="";
			List <Element> hijos= elemento.getChildElements();
			for(int i=0;i<hijos.size();i++){
				if(!hijos.get(i).getTextExtractor().toString().isEmpty()){
					resto+=(hijos.get(i).getTextExtractor().toString());
					if(i<hijos.size()-1)
					resto+=" ";
				}
				
			}
			String resultado="";
			if(todo.length()> resto.length()){
			  resultado=todo.substring(0, todo.length()-resto.length()-1);
			}
			rta=resultado.equals(templateNode.getTitle());
	
		}
		
	}
	
	return rta;
}

private void validarHijos(UrlWrapper newElement, Iterator<Element> elementos,
		Element next, TemplateStructure templateNode) {
	// TODO Auto-generated method stub
	
}

private boolean matching(Element elemento, TemplateStructure templateNode,boolean validarHijos) {
	boolean rta=false;
	
	if(!validarHijos){
		  
			if(isLink(elemento)){
				
				rta=  elemento.getRenderer().toString().equals(templateNode.getTitle());
			}else{
				
				if(elemento.getChildElements().isEmpty()){
					rta=  elemento.getRenderer().toString().equals(templateNode.getTitle());
				}else
				{
					String todo = elemento.getTextExtractor().toString();
					String resto="";
					List <Element> hijos= elemento.getChildElements();
					for(int i=0;i<hijos.size();i++){
						if(!hijos.get(i).getTextExtractor().toString().isEmpty()){
							resto+=(hijos.get(i).getTextExtractor().toString());
							if(i<hijos.size()-1)
							resto+=" ";
						}
						
					}
					String resultado="";
					if(todo.length()> resto.length()){
					  resultado=todo.substring(0, todo.length()-resto.length()-1);
					}
					rta=resultado.equals(templateNode.getTitle());
				  
				  // (elemento.getBegin(), elemento.getChildElements().get(0).getBegin()).toString();
				}
	//			elemento.subSequence(elemento.getBegin(),  elemento.getContent().getFirstStartTag().getBegin());
		       }
		}else{
			rta=validarHijos;
		}
		return rta;
}

}
